/**
 * 微信公众号登录
 * https://segmentfault.com/a/1190000044774873
 */
// const dayjs = require('dayjs')
const axios = require('axios')
const sha1 = require('crypto-js/sha1');
const Router = require('@koa/router');
const { sign } = require('jsonwebtoken')

const env = require('../../env')
const utils = require('../../utils');
const WxRedis = require('../../redis/weixin');
const { User } = require('../../db/schemas/index')

const router = new Router({ prefix: '/public/weixin' })

// const WeixinTokenFilter = { key: 'access_token' }

/**
 * 微信回调
 * 验签（配置公众号时）
 * */
router.get('/receive', async (ctx) => {
  const { signature, timestamp, nonce, echostr } = ctx.query
  // console.log(signature, timestamp, nonce, echostr)

  const tmpArr = [env.WEIXIN.token, timestamp, nonce]
  tmpArr.sort()
  const tmpStr = sha1(tmpArr.join('')).toString()

  ctx.body = tmpStr === signature ? echostr : utils.genResponse(false)
})

/**
 * 微信回调
 * 处理扫码（用户扫码时）
 */
router.post('/receive', async (ctx) => {
  const access_token = await WxRedis.AccessToken.get()
  const {
    ToUserName,
    FromUserName,
    CreateTime,
    MsgType,
    Event,
    EventKey,
    Ticket,
  // @ts-ignore
  } = ctx.request.body.xml
  const ticket = Ticket[0]

  const {
    signature,
    timestamp,
    nonce,
    openid,
  } = ctx.query

  // 用户信息
  // https://developers.weixin.qq.com/doc/offiaccount/User_Management/Get_users_basic_information_UnionID.html#UinonId
  // const unionidUrl = `https://api.weixin.qq.com/cgi-bin/user/info?access_token=${access_token}&openid=${openid}&lang=zh_CN`
  // const unionidRes = await axios(unionidUrl)
  // const { status, statusText, data } = unionidRes
  // console.log(status, statusText, data);

  const findDoc = await User.find({ openid }).lean()

  if (!findDoc) {
    // 创建用户
    const userDoc = new User({ openid })
    await userDoc.save()
  }

  // 更新 ticket 的值为 openid
  await WxRedis.Ticket.update(ticket, openid)

  const msgBody = `<xml>
    <ToUserName><![CDATA[${FromUserName}]]></ToUserName>
    <FromUserName><![CDATA[${ToUserName}]]></FromUserName>
    <CreateTime>${Date.now()}</CreateTime>
    <MsgType><![CDATA[text]]></MsgType>
    <Content><![CDATA[登录成功，祝您生活愉快！]]></Content>
  </xml>
  `
  ctx.body = msgBody
})

/**
 * 生成带参数的二维码
 * https://developers.weixin.qq.com/doc/offiaccount/Account_Management/Generating_a_Parametric_QR_Code.html
 * 返回 {ticket,expire_seconds,url}
 * https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=${ticket}
 * */
router.get('/ticket', async (ctx) => {
  const scene_id = utils.random(1, 100000)

  const access_token = await WxRedis.AccessToken.get()

  // todo access_token undefined 判断
  const url = `https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=${access_token}`
  const body = {
    action_name: 'QR_LIMIT_SCENE', // QR_SCENE-临时二维码 QR_LIMIT_SCENE-永久二维码
    action_info: {
      scene: {
        scene_id // 值任意，会在扫码回调里面返回
      }
    }
  }
  try {
    const res = await axios.post(url, body)
    const ticket = res.data.ticket
    await WxRedis.Ticket.set(ticket)
    const qrcode = `https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=${ticket}`
    ctx.body = utils.genResponse(true, { ticket, qrcode })
  } catch (error) {
    ctx.body = utils.genResponse(false, error.toString())
  }
})

/**
 * 查询二维码扫码状态
 */
router.get('/query-ticket', async function(ctx) {
  const { ticket } = ctx.query

  const openid = await WxRedis.Ticket.get(ticket)

  if (openid === 'null') {
    ctx.body = utils.genResponse(false)
    return
  }

  await WxRedis.Ticket.remove(ticket)

  const token = sign({ openid }, env.JWT.secret, { expiresIn: '3h' })
  ctx.cookies.set(env.JWT.name, token, {
    domain: env.COOKIE.domain,
    path: '/',
    maxAge: 3 * 60 * 60 * 1000,
    httpOnly: true,
    overwrite: true,
  })
  ctx.body = utils.genResponse(true)
})

module.exports = router